package particleField;

import javax.media.opengl.GL;

import processing.core.*; 
import processing.opengl.PGraphicsOpenGL;

public class Particle {
	  final PVector home;
	  PVector loc;
	  PVector vel;
	  PVector acc;
	  boolean force_home;
	  float r;
	  float timer;
	  int update;
	  PVector[][] magneticField;
	  int color;
	  int velo_height;
	  
	  // Another constructor (the one we are using here)
	  Particle(PVector l, PVector[][] magneticField) {
		home = l.get();
	    acc = new PVector(/*0.005F,0.01F,0*/0,0);
	    vel = new PVector(/* -0.01F, 0.5F, 0*/0,0);
	    loc = l.get();
	    r = 2.0F;
	    timer = (float) ( (Math.random()) * 90 +60);
	    this.magneticField = magneticField;
	    color = 0x000000FF;
	    velo_height = 0;
	  }

	  // Method to update location
	  void update() {
		  float rand_vel = (float) ( (Math.random()-0.5) * 0.1 );
		  float rand_vel2 = (float) ( (Math.random()-0.5) * 0.1);
		  
		  loc.add( rand_vel, rand_vel2, 0);
		  
		  if(loc.x < 0 || loc.y < 0 ||  loc.x > magneticField.length-1 || loc.y > magneticField[0].length-1 ){			 
			  vel.mult(-0.2f);
		  }else{
			  loc.add(magneticField[(int)loc.x][(int)loc.y]);
		  }
		  
		  loc.add(vel);
		  vel.mult(0.98f);
		  color = (int) (distance(vel)/2.0 * 255);
		  velo_height = (int) (distance(vel)/2.0 * 2 + 1);
	  }
	  
	  private void force_add(PVector magnet, boolean againstMagnetic){		 
		  PVector force;
		  float diff_x = magnet.x - loc.x;
		  float diff_y = magnet.y - loc.y;
		  
		  if( Math.abs(diff_x) > 1 && Math.abs(diff_y) > 1){
			  double angle = Math.atan2( (diff_y), (diff_x) )*180/Math.PI;
		 
		  
			  int x_offs = getx_Polar(3, angle);
			  int y_offs = gety_Polar(3, angle);
			  
			  if(againstMagnetic == false){
				  force = new PVector(x_offs, y_offs);
			  }else{
				  force = new PVector(-x_offs, -y_offs);
			  }
			  
			  loc.add(force);
			  
		  }else{
			  loc.set(home);
		  }
	  }
	  
	  public void force_home(){
		  force_home = true;
	  }
	  
	  public void force_disable_home(){
		  force_home = false;
	  }

	  // Method to display
	  void render(PApplet pa) {
//		pa.ellipseMode(pa.CENTER);
//		pa.noStroke();
		
//		pa.fill( 15,255);		
//		pa.ellipse(loc.x, loc.y, r,r);
		
//		PGraphicsOpenGL glb = (PGraphicsOpenGL) pa.g;
//		GL gl = glb.beginGL();
//		gl.glRectf(loc.x, loc.y, loc.x+1, loc.y+1);
//		glb.endGL();

		//createGradient(pa, loc.x, loc.y, r*timer/150, pa.color(0, 0, 0), pa.color(255, 255, 255));
		
//		pa.fill( 100 ,50);
		//pa.ellipse(loc.x-5,loc.y+5,r*timer/150,r*timer/150);
		
	    //displayVector(vel,loc.x,loc.y,10, pa);
	  }
	  
	  // Is the particle still useful?
	  boolean dead() {
	    /*if (timer <= 0.0) {
	      return true;
	    } else {
	      return false;
	    }*/
//		  if(loc.x < 0 || loc.y > magneticField.length || loc.y < 0 || loc.x > magneticField[0].length){
//			  return true;
//		  }else{
//			  return false;
//		  }
		  return false;
			  
	  }
	  
	   void displayVector(PVector v, float x, float y, float scayl, PApplet pa) {
		pa.pushMatrix();
	    float arrowsize = 4;
	    // Translate to location to render vector
	    pa.translate(x,y);
	    pa.stroke(255);
	    // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate
	    pa.rotate(v.heading2D());
	    // Calculate length of vector & scale it to be bigger or smaller if necessary
	    float len = v.mag()*scayl;
	    // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)
	    pa.line(0,0,len,0);
	    pa.line(len,0,len-arrowsize,+arrowsize/2);
	    pa.line(len,0,len-arrowsize,-arrowsize/2);
	    pa.popMatrix();
	  } 
	   
	   
		private int getx_Polar(double radius, double angle){
			return (int) (radius*(Math.cos(angle/360*2*Math.PI)) );
		}
		
		private int gety_Polar(double radius, double angle){
			return (int) (radius*(Math.sin(angle/360*2*Math.PI)) );
		}
		
		private int distance(PVector v){
			return (int)Math.sqrt(v.x*v.x +v.y*v.y);
		}
		
		private float getAngle(PVector v){
			return (float)(Math.atan2(v.y, v.x)*180/Math.PI);
		}

	}